package bridge

import (
	"context"
	"errors"
	"fmt"
	"log"
)

// 注册式工厂，支持动态注册，比如配置项里添加，直接注册
type AlertFactory2 struct {
	registry map[string]func() AlertInterface
}

func NewAlertFactory2() *AlertFactory2 {
	return &AlertFactory2{
		registry: make(map[string]func() AlertInterface),
	}
}

func (f *AlertFactory2) Register(name string, constructor func() AlertInterface) {
	f.registry[name] = constructor
}

func (f *AlertFactory2) Create(name string) (AlertInterface, error) {
	if ctor, ok := f.registry[name]; ok {
		return ctor(), nil
	}
	return nil, fmt.Errorf("alert type %s not registered", name)
}

// 缓存式工厂，实例都缓存在结构体中，但是在初始化时候缓存，不支持动态加载
type AlertFactory struct {
	alertMap map[string]AlertInterface
}

// 构建式添加notify
func NewAlertFactory(alertMap map[string]AlertInterface) *AlertFactory {
	return &AlertFactory{alertMap: alertMap}
}

func (a *AlertFactory) CreateAlert(types string) (AlertInterface, error) {
	if alert, ok := a.alertMap[types]; ok {
		return alert, nil
	}

	return nil, errors.New("CreateAlert error. no alert type")
}

type AlertInterface interface {
	Alert(ctx context.Context, notifyInfo NotifyInfo) error
}

type UrgencyAlert struct {
	notifyList []NotifyInterface
}

func NewUrgencyAlert(notifyList ...NotifyInterface) *UrgencyAlert {
	return &UrgencyAlert{notifyList: notifyList}
}

// AddNotify 注册式添加nofity
func (a *UrgencyAlert) AddNotify(n NotifyInterface) error {
	a.notifyList = append(a.notifyList, n)
	return nil
}

func (a *UrgencyAlert) Alert(ctx context.Context, notifyInfo NotifyInfo) error {
	for _, notify := range a.notifyList {
		err := notify.Notify(ctx, notifyInfo)
		if err != nil {
			log.Printf("Notify Err: %s\n", err.Error())
		}
	}

	return nil
}

type NormalAlert struct {
	notifyList []NotifyInterface
}

// 构建式添加notify
func NewNormalAlert(notifyList ...NotifyInterface) *UrgencyAlert {
	return &UrgencyAlert{notifyList: notifyList}
}

// AddNotify 注册式添加nofity
func (a *NormalAlert) AddNotify(n NotifyInterface) error {
	a.notifyList = append(a.notifyList, n)
	return nil
}

func (a *NormalAlert) Alert(ctx context.Context, notifyInfo NotifyInfo) error {
	for _, notify := range a.notifyList {
		err := notify.Notify(ctx, notifyInfo)
		if err != nil {
			log.Printf("Notify Err: %s\n", err.Error())
		}
	}

	return nil
}

type TrivialAlert struct {
	notifyList []NotifyInterface
}

// 构建式添加notify
func NewTrivialAlert(notifyList ...NotifyInterface) *UrgencyAlert {
	return &UrgencyAlert{notifyList: notifyList}
}

// AddNotify 注册式添加nofity
func (a *TrivialAlert) AddNotify(n NotifyInterface) error {
	a.notifyList = append(a.notifyList, n)
	return nil
}

func (a *TrivialAlert) Alert(ctx context.Context, notifyInfo NotifyInfo) error {
	for _, notify := range a.notifyList {
		err := notify.Notify(ctx, notifyInfo)
		if err != nil {
			log.Printf("Notify Err: %s\n", err.Error())
		}
	}

	return nil
}
